﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Nest;

namespace Infrastructure.ElasticSearch.ParentChilds
{
    public static class SearchDescriptorExtension
    {
        public static SearchDescriptor<T> DateRange<T>(
            DateTime? valueDateBegin,
            DateTime? valueDateEnd,
            Expression<Func<T, string>> field) where T : class
        {
            return new SearchDescriptor<T>().Query(q => q
                .DateRange(m =>
                    {
                        var res = m.Field(field);
                        if (valueDateBegin != null)
                            res.GreaterThanOrEquals(
                                valueDateBegin.Value.ToString("yyyy-MM-dd HH:mm:ss"));
                        if (valueDateEnd != null)
                            res.LessThanOrEquals(valueDateEnd.Value.ToString("yyyy-MM-dd HH:mm:ss"));
                        return res;
                    }
                )
            );
        }

        public static SearchDescriptor<T> NumRange<T>(this SearchDescriptor<T> searchDescriptor,
            int? valueNumBegin, int? valueNumEnd, Expression<Func<T, int>> field) where T : class
        {
            return new SearchDescriptor<T>().Query(q => q
                .Range(m =>
                    {
                        var res = m.Field(field);
                        if (valueNumBegin != null)
                            res.GreaterThanOrEquals(
                                valueNumBegin.Value);
                        if (valueNumEnd != null)
                            res.LessThanOrEquals(valueNumEnd.Value);
                        return res;
                    }
                )
            );
        }

        public static SearchDescriptor<T> StringMatchPhrase<T>(
            string value,
            Expression<Func<T, string>> field) where T : class
        {
            return new SearchDescriptor<T>().Query(q => q
                .MatchPhrase(m => m
                    .Field(field)
                    .Query(value)
                )
            );
        }

        public static SearchDescriptor<T> StringTerms<T>(
            List<string> values,
            Expression<Func<T, string>> field) where T : class
        {
            return new SearchDescriptor<T>().Query(q => q
                .Terms(m => m
                    .Field(field)
                    .Terms(values)
                )
            );
        }

        public static SearchDescriptor<T> StringMatch<T>(
            string value,
            Expression<Func<T, string>> field) where T : class
        {
            return new SearchDescriptor<T>().Query(q => q
                .Match(m => m
                    .Field(field)
                    .Query(value)
                )
            );
        }

        public static SearchDescriptor<T> Must<T>(
            IEnumerable<Func<QueryContainerDescriptor<T>, QueryContainer>> queries) where T : class
        {
            return new SearchDescriptor<T>().Query(q => q
                .Bool(b => b
                    .Must(queries)
                )
            );
        }

        public static SearchDescriptor<T> Should<T>(
            IEnumerable<Func<QueryContainerDescriptor<T>, QueryContainer>> queries) where T : class
        {
            return new SearchDescriptor<T>().Query(q => q
                .Bool(b => b
                    .Should(queries)
                )
            );
        }
    }
}